package com.shop.shopserver.provider;

import com.shop.shopcommon.token.CustomUser;
import com.shop.shopserver.service.PasswordUserDetailsService;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Component
public class CustomUsernamePasswordAuthenticationProvider extends DaoAuthenticationProvider {

    public CustomUsernamePasswordAuthenticationProvider(PasswordUserDetailsService passwordUserDetailsService) {
        setUserDetailsService(passwordUserDetailsService);
        setPasswordEncoder(passwordEncoder());
    }
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取用户名和密码
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        // 调用父类方法加载用户信息
        CustomUser userDetails = (CustomUser) retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);

        // 自定义认证逻辑：验证密码
        if (!passwordEncoder().matches(password, userDetails.getPassword())) {
            throw new BadCredentialsException("Invalid password");
        }

        // 调用父类方法完成认证
        return super.authenticate(authentication);
    }

    @Override
    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        // 使用父类提供的公共方法 getAuthorizedAuthorities 替代直接访问 authoritiesMapper
        UsernamePasswordAuthenticationToken result = UsernamePasswordAuthenticationToken.authenticated(
                principal,
                authentication.getCredentials(),
                this.getAuthorizedAuthorities(user.getAuthorities(), authentication)
        );

        // 设置认证令牌的详细信息
        Map<String, Long> map = new HashMap<>();
        map.put("id", ((CustomUser)user).getId());
        result.setDetails(map);

        // 返回认证结果
        return result;
    }

    private Collection<? extends GrantedAuthority> getAuthorizedAuthorities(Collection<? extends GrantedAuthority> authorities, Authentication authentication) {
        return authorities;
    }

    /**
     * 密码加密器
     */
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return org.springframework.security.authentication.UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
